/**
 * 管理内存
 * 如何释放内存实例
 */
// 数字 释放
void malloc1()
{
	int *a;

    a = (int *)malloc(sizeof(int) * 5);
	if (a == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	*a = 111;
    printf("数字 释放内存:%d => %d\n\n", a, *a);

	free(a);
	a = NULL;
}
// 数字 释放

// 字符串 释放内存
void malloc2()
{
    char *a;

    a = (char *)malloc(sizeof(char) * 10);
	if (a == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	strcpy(a, "malloc2"); // 注意末尾有个 \0 结束符，所以只能最多9个字符
    printf("字符串 释放内存:%d => %s\n\n", &a, a);

	free(a);
	a = NULL;
}
// 字符串 释放内存

// 数字 函数外释放内存
int * malloc33()
{
    int *a;

	a = (int*)malloc(sizeof(int) * 5);
	if (a == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	*a = 333;
    return a;
}

void malloc3()
{
	int *a;
	a = malloc33();
	printf("数字 函数外释放内存：%d => %d\n\n", a, *a);

	free(a);
	a = NULL;
}
// 数字 函数外释放内存

// 字符串 函数外释放内存
char * malloc44()
{
	char *a;

	a = (char*)malloc(sizeof(char) * 10);
	if (a == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	a = "malloc44";
	return a;
}

void malloc4()
{
	char *a, *b, *c;
	int i;

	a = malloc44();
	printf("字符串 函数外释放内存：%d => %s\n\n", &a, a);

	free(a);
	a = NULL;
}
// 字符串 函数外释放内存

// 数字数组 函数外释放内存
int * malloc55(int len)
{
	int *arr, i;

    arr = (int *)malloc(sizeof(int) * len);
	if (arr == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	for (i = 0; i < len; ++i) 
	{
		*(arr + i) = i;
	}

	return arr;
}

void malloc5()
{
    int *a;

	a = malloc55(2);
	printf("数字数组 函数外释放内存a[0]：%d => %d\n", &a[0], a[0]);
	printf("数字数组 函数外释放内存a[1]：%d => %d\n\n", &a[1], a[1]);

	free(a);
	a = NULL;
}
// 数字数组 函数外释放内存

// 字符串数组 函数外释放内存
char ** malloc66(int len)
{
	char *a[62] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}, **arr;
	int i;

    arr = (char **)malloc(sizeof(char*) * len);
	if (arr == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	for (i = 0; i < len; ++i)
	{
		// arr[i] = (char *) malloc(sizeof(char) * 1); // 2个谁家字符就 * 2
		arr[i] = a[rand() % 63];
	}

	return arr;
}

void malloc6()
{
	char **a;

	a = malloc66(2);
	printf("字符串数组 函数外释放内存a[0]：%d => %s\n", &a[0], a[0]);
	printf("字符串数组 函数外释放内存a[1]：%d => %s\n", &a[1], a[1]);

	free(a);
	a = NULL;

	printf("字符串数组 函数外释放内存后：%d\n\n", &a);
	// 释放后 不能访问 a[0]
}
// 字符串数组 函数外释放内存

//自定义结构体 函数外释放内存
typedef struct malloc7_tag
{
	int i;
	float f;
	char c;
	char *d;
} malloc7_struct;

malloc7_struct * getStructArray()
{
	struct malloc7_tag *strarr;

	strarr = (malloc7_struct *)malloc(sizeof(malloc7_struct));
	if (strarr == NULL) {
		printf("分配内存失败！！\n");
		exit(0);
	}

	// 对象访符号 ->
	strarr -> i = 1;
	strarr -> f = 1.1;
	strarr -> c = 'c';
	strarr -> d = "d";

	return strarr;
}

void malloc7()
{
	struct malloc7_tag *arr;
	arr = getStructArray();
	printf("自定义结构体 函数外释放内存：\n");
    printf("int : %d float: %f char: %c char*: %s\n", arr->i, arr->f, arr->c, arr->d);
	printf("自定义结构体 内存地址：%d\n", arr);
    
	free(arr);
	arr = NULL;

	printf("自定义结构体 函数外释放内存后：\n");
	printf("自定义结构体 内存地址：%d\n", arr);
}
//自定义结构体 函数外释放内存

void Malloc()
{
    malloc1(); // 数字 释放
    malloc2(); // 字符串 释放
	malloc3(); // 数字 函数外释放
	malloc4(); // 字符串 函数外释放
    malloc5(); // 数字数组 函数外释放内存
	malloc6(); // 字符串数组 函数外释放内存
	malloc7(); // 自定义结构体 函数外释放内存
}